package com.pp.ent.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.text.TextUtils;

import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.DatabaseTable;
import com.j256.ormlite.table.TableUtils;
import com.pp.ent.Cherry;
import com.pp.ent.base.inject.PackageUtils;
import com.pp.ent.base.log.MLog;

import java.sql.SQLException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import dalvik.system.PathClassLoader;

/**
 * Created by dengqu on 2017/2/24.
 */

public class DbManager {
    private static final String TAG = "DbManager";
    private static final int CORE_DB_VERSION = 1;
    private static DbContext coreDbContext;
    private static Set<String> clazzs = new HashSet();
    public static final String ON_DB_UPGRADE = "com.yy.ent.cherry.ext.db.onDbUpgrade";

    public static void init(Context ctx, String packages, String dbName) {
        init(ctx, packages, dbName, CORE_DB_VERSION);
    }

    public static void init(final Context ctx, String packages, String dbName, final int newVersion) {
        MLog.info("DbManager", "DbManager init");
        if ((TextUtils.isEmpty(packages)) || (TextUtils.isEmpty(dbName))) {
            MLog.error("DbManager", "packages or dbName is empty,please set");
            return;
        }
        initClass(ctx, new String[]{packages});
        if (coreDbContext == null) {
            coreDbContext = new DbThread("CoreDbThread", dbName + ".db") {
                public void createDbHelper(String dbName) {
                    this.logger.info("DbManager createDbHelper for " + dbName);
                    this.dbHelper = new DbHelper(ctx, dbName, newVersion) {
                        protected void onDbUpgrade(SQLiteDatabase database, ConnectionSource connectionSource, int oldVersion, int newVersion)
                                throws SQLException {
                            MLog.info("DbManager", "onDbUpgrade oldVersion=" + oldVersion + ",newVersion=" + newVersion);
                            if (oldVersion == 1) {
                                DbManager.createTable(connectionSource, 1);
                            } else {
                                MLog.info("DbManager", "onDbUpgrade notityServices uri=com.yy.ent.cherry.ext.db.onDbUpgrade,oldVersion=" + oldVersion + ",newVersion=" + newVersion);
                                Cherry.notifyService("com.yy.ent.cherry.ext.db.onDbUpgrade", new Object[]{database, connectionSource, Integer.valueOf(oldVersion), Integer.valueOf(newVersion)});
                            }
                        }

                        protected void onDbCreate(SQLiteDatabase database, ConnectionSource connectionSource)
                                throws SQLException {
                            DbManager.createTable(connectionSource, 2);
                            MLog.info("DbManager", "onDbCreate ");
                        }

                        public void onOpen(SQLiteDatabase db) {
                            MLog.info("DbManager", "onOpen ");
                        }
                    };
                    try {
                        this.dbHelper.getWritableDatabase();
                    } catch (Exception e) {
                        MLog.error("DbManager", "DBManager CoreDbThread can not get writable database");
                    }
                }
            };
            coreDbContext.open();
        }
    }

    public static void initClass(Context gContext, String... packages) {
        for (String perPak : packages) {
            String[] classes = PackageUtils.findClassesInPackage(perPak, gContext);
            Collections.addAll(clazzs, classes);
        }
    }

    public static void createTable(ConnectionSource connectionSource, int flag)
            throws SQLException {
        MLog.debug("DbManager", "createTable flag=" + flag);
        for (String clazzName : clazzs) {
            try {
                PathClassLoader classLoader = (PathClassLoader) Thread.currentThread().getContextClassLoader();

                MLog.debug("DbManager", "invoke class forname:" + clazzName);
                Class<?> clazz = null;
                clazz = Class.forName(clazzName, true, classLoader);
                MLog.debug("DbManager", "invoke class forname over");
                DatabaseTable beanAnnotation = (DatabaseTable) clazz.getAnnotation(DatabaseTable.class);
                if ((beanAnnotation != null) && (!clazz.isAnonymousClass())) {
                    MLog.debug("DbManager", "create table class forname :"+clazzName);
                    if (flag == 1) {
                        TableUtils.dropTable(connectionSource, clazz, true);
                        TableUtils.createTable(connectionSource, clazz);
                    } else {
                        TableUtils.createTable(connectionSource, clazz);
                    }
                }
            } catch (ClassNotFoundException e) {
                MLog.error("DbManager", "CreateTable fail");
            }
        }
    }

    public static DbContext getDbContext() {
        return coreDbContext;
    }

    public static DbHelper getDbHelper() {
        return getDbContext().getDbHelper();
    }
}
